package cn.matrix42.potoo.jdbc.connection;

import cn.matrix42.potoo.jdbc.dialect.Dialect;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class ConnectionAgent implements AutoCloseable {

    private final ConnectionInfo connectionInfo;
    private final Dialect dialect;
    private final Connection connection;

    public ConnectionAgent(ConnectionInfo connectionInfo, Dialect dialect) throws SQLException {
        this.connectionInfo = connectionInfo;
        this.dialect = dialect;
        this.connection = initConnection();
    }

    private Connection initConnection() throws SQLException {
        String url = connectionInfo.getUrl();
        String username = connectionInfo.getUsername();
        String password = connectionInfo.getPassword();
        Properties properties = connectionInfo.getProperties();

        if (properties == null) {
            if (username == null) {
                return DriverManager.getConnection(url);
            } else {
                return DriverManager.getConnection(url, username, password);
            }
        } else {
            return DriverManager.getConnection(url, properties);
        }
    }

    public PreparedStatement getInsertIntoStatement(String tableName, String[] fieldNames) throws SQLException {
        String sql = dialect.getInsertIntoStatement(tableName, fieldNames);
        return connection.prepareStatement(sql);
    }

    public PreparedStatement getUpdateStatement(String tableName, String[] fieldNames, String[] conditionFields) throws SQLException {
        String sql = dialect.getUpdateStatement(tableName, fieldNames, conditionFields);
        return connection.prepareStatement(sql);
    }

    public PreparedStatement getDeleteStatement(String tableName, String[] conditionFields) throws SQLException {
        String sql = dialect.getDeleteStatement(tableName, conditionFields);
        return connection.prepareStatement(sql);
    }

    public PreparedStatement getSelectFromStatement(String tableName, String[] selectFields, String[] conditionFields) throws SQLException {
        String sql = dialect.getSelectFromStatement(tableName, selectFields, conditionFields);
        return connection.prepareStatement(sql);
    }

    public PreparedStatement getExistsStatement(String tableName, String[] conditionFields) throws SQLException {
        String sql = dialect.getRowExistsStatement(tableName, conditionFields);
        return connection.prepareStatement(sql);
    }

    public Statement createStatement() throws SQLException {
        return connection.createStatement();
    }

    public Connection getConnection() {
        return connection;
    }

    @Override
    public void close() throws Exception {
        if (connection != null) {
            connection.close();
        }
    }
}
